/**
 * This software is copyrighted by Bosch Connected Devices and Solutions GmbH, 2016.
 * The use of this software is subject to the XDK SDK EULA
 */

/* module includes ********************************************************** */

/* system header files */
#include "BCDS_Basics.h"

/* own header files */
#include "BCDS_Environmental.h"
#include "Environmental.h"

/* additional interface header files */
#include "BCDS_Bme280Utils.h"
#include <bme280.h>

/* local variables ********************************************************** */

/* global variables ********************************************************* */
static const uint8_t modeLookUpTable[ENVIRONMENTAL_POWERMODE_OUT_OF_RANGE] = {
        UINT8_C(BME280_SLEEP_MODE),
        UINT8_C(BME280_FORCED_MODE),
        UINT8_C(BME280_NORMAL_MODE)
};


static const uint8_t standbytimeLookUpTable[ENVIRONMENTAL_STANDBY_TIME_OUT_OF_RANGE] =
{
    UINT8_C(BME280_STANDBY_TIME_1_MS),
    UINT8_C(BME280_STANDBY_TIME_63_MS),
    UINT8_C(BME280_STANDBY_TIME_125_MS),
    UINT8_C(BME280_STANDBY_TIME_250_MS),
    UINT8_C(BME280_STANDBY_TIME_500_MS),
    UINT8_C(BME280_STANDBY_TIME_1000_MS),
    UINT8_C(BME280_STANDBY_TIME_10_MS),
    UINT8_C(BME280_STANDBY_TIME_20_MS)
};

static const uint8_t filterCoeffLookUpTable[ENVIRONMENTAL_FILTER_COEFF_OUT_OF_RANGE] =
{
    UINT8_C(BME280_FILTER_COEFF_OFF),
    UINT8_C(BME280_FILTER_COEFF_2),
    UINT8_C(BME280_FILTER_COEFF_4),
    UINT8_C(BME280_FILTER_COEFF_8),
    UINT8_C(BME280_FILTER_COEFF_16)
};

static const uint8_t overSamplingLookUpTable[ENVIRONMENTAL_OVERSAMP_OUT_OF_RANGE] =
{
    UINT8_C(BME280_OVERSAMP_SKIPPED),
    UINT8_C(BME280_OVERSAMP_1X),
    UINT8_C(BME280_OVERSAMP_2X),
    UINT8_C(BME280_OVERSAMP_4X),
    UINT8_C(BME280_OVERSAMP_8X),
    UINT8_C(BME280_OVERSAMP_16X)
};

/* inline functions ********************************************************* */

/* local functions ********************************************************** */
static Retcode_T bme280LibErrorMapping(BME280_RETURN_FUNCTION_TYPE BME280_libReturn)
{
    Retcode_T returnValue = (Retcode_T) RETCODE_FAILURE;

    if (SUCCESS == BME280_libReturn)
    {
        returnValue = (Retcode_T) RETCODE_SUCCESS;
    }
    else if (E_BME280_NULL_PTR == BME280_libReturn)
    {
        returnValue = (Retcode_T) RETCODE_INVALID_PARAM;
    }
    else
    {
        returnValue = (Retcode_T) RETCODE_FAILURE;
    }
    return (returnValue);
}

static int8_t mappingEnumForGetFunctions(uint8_t start, uint8_t end, uint8_t getValueToBeTransalated, const uint8_t * lookUpTablePtr)
{
    uint8_t i = UINT8_C(0);
    int8_t apiReturnValue = GET_MAPPING_ERROR;

    for (i = start; i <= end; i++)
    {
        if (getValueToBeTransalated == *(lookUpTablePtr + i))
        {
            apiReturnValue = i;
            break;
        }
    }

    return (apiReturnValue);
}

static Retcode_T setOverSampling(int8_t ParamType, Environmental_HandlePtr_T handle, Environmental_OverSampling_T samplingRate)
{
    Retcode_T sensorReturnValue = (Retcode_T) RETCODE_FAILURE;

    Environmental_PowerModes_T PowerMode = ENVIRONMENTAL_BME280_POWERMODE_SLEEP;

    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (Retcode_T ) RETCODE_INVALID_PARAM));
    }
    if (samplingRate >= ENVIRONMENTAL_OVERSAMP_OUT_OF_RANGE)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (Retcode_T ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (Retcode_T ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:
        if (samplingRate > ENVIRONMENTAL_BME280_OVERSAMP_16X)
        {
            sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {
            if (TEMPERATURE == ParamType)
            {
                /*collect the current power mode settings before calling this API*/
                sensorReturnValue = Environmental_getPowerMode(handle, &PowerMode);
                if (RETCODE_OK == sensorReturnValue)
                {
                    sensorReturnValue = Environmental_setPowerMode(handle, ENVIRONMENTAL_BME280_POWERMODE_SLEEP);
                }
                if (RETCODE_OK == sensorReturnValue)
                {

                    libBme280ReturnValue = bme280_set_oversamp_temperature(overSamplingLookUpTable[samplingRate]);

                    sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
                }
                if (RETCODE_OK == sensorReturnValue)
                {
                    /*Re-Set the last user set power mode settings */
                    sensorReturnValue = Environmental_setPowerMode(handle, PowerMode);
                }
            }
            else if (PRESSURE == ParamType)
            {
                /*collect the current power mode settings before calling this API*/
                sensorReturnValue = Environmental_getPowerMode(handle, &PowerMode);
                if (RETCODE_OK == sensorReturnValue)
                {
                    sensorReturnValue = Environmental_setPowerMode(handle, ENVIRONMENTAL_BME280_POWERMODE_SLEEP);
                }
                if (RETCODE_OK == sensorReturnValue)
                {

                    libBme280ReturnValue = bme280_set_oversamp_pressure(overSamplingLookUpTable[samplingRate]);

                    sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
                }
                if (RETCODE_OK == sensorReturnValue)
                {
                    /*Re-Set the last user set power mode settings */
                    sensorReturnValue = Environmental_setPowerMode(handle, PowerMode);
                }
            }
            else if (HUMIDITY == ParamType)
            {
                /*collect the current power mode settings before calling this API*/
                sensorReturnValue = Environmental_getPowerMode(handle, &PowerMode);
                if (RETCODE_OK == sensorReturnValue)
                {
                    sensorReturnValue = Environmental_setPowerMode(handle, ENVIRONMENTAL_BME280_POWERMODE_SLEEP);
                }
                if (RETCODE_OK == sensorReturnValue)
                {

                    libBme280ReturnValue = bme280_set_oversamp_humidity(overSamplingLookUpTable[samplingRate]);

                    sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
                }
                if (RETCODE_OK == sensorReturnValue)
                {
                    /*Re-Set the last user set power mode settings */
                    sensorReturnValue = Environmental_setPowerMode(handle, PowerMode);
                }
            }
            else
            {
                sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
            }
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }
    if ((RETCODE_OK != sensorReturnValue) && (Retcode_getPackage(sensorReturnValue) == PACKAGE_ID_DEFAULT))
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}
/* global functions ********************************************************* */

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_init(Environmental_HandlePtr_T handle)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (handle->SensorInformation.initializationStatus == INIT_DONE)
    {
        return (RETCODE_OK);
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:
        sensorReturnValue = Bme280Utils_initialize((Bme280Utils_InfoPtr_T) handle->SensorPtr);

        if (RETCODE_OK == sensorReturnValue)
        {
            handle->SensorInformation.initializationStatus = INIT_DONE;
        }
        else
        {
            handle->SensorInformation.initializationStatus = INIT_NOT_DONE;
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != sensorReturnValue) && (Retcode_getPackage(sensorReturnValue) == PACKAGE_ID_DEFAULT))
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setPowerMode(Environmental_HandlePtr_T handle, Environmental_PowerModes_T mode)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (mode >= ENVIRONMENTAL_POWERMODE_OUT_OF_RANGE)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:
        if (mode > ENVIRONMENTAL_BME280_POWERMODE_NORMAL)
        {
            sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {

            libBme280ReturnValue = bme280_set_power_mode(modeLookUpTable[mode]);

            sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_getPowerMode(Environmental_HandlePtr_T handle, Environmental_PowerModesPtr_T mode)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);
    Environmental_PowerModes_T tempmode = ENVIRONMENTAL_POWERMODE_OUT_OF_RANGE;
    int8_t tempretVal = GET_MAPPING_ERROR;

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == mode))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:


        libBme280ReturnValue = bme280_get_power_mode((uint8_t *) mode);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        if (RETCODE_OK == sensorReturnValue)
        {
            tempmode = *mode;
            tempretVal = mappingEnumForGetFunctions((uint8_t) ENVIRONMENTAL_BME280_POWERMODE_SLEEP, (uint8_t) ENVIRONMENTAL_BME280_POWERMODE_NORMAL, (uint8_t) tempmode, modeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *mode = (Environmental_PowerModes_T) tempretVal;
            }
            else
            {
                sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readData(Environmental_HandlePtr_T handle, Environmental_DataPtr_T sensorData)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == sensorData))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

        libBme280ReturnValue = bme280_read_pressure_temperature_humidity((unsigned int*) &sensorData->pressure, (int *) &sensorData->temperature, (unsigned int *) &sensorData->humidity);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        if (RETCODE_OK == sensorReturnValue)
        {
            sensorData->humidity = (sensorData->humidity / ENVI_BME280_HUM_RH_CONV);
            sensorData->temperature = (sensorData->temperature * ENVI_BME280_TEMP_MIILIDEG_CONV);
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readDataLSB(Environmental_HandlePtr_T handle, Environmental_LsbDataPtr_T sensorData)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == sensorData))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

    libBme280ReturnValue = bme280_read_uncomp_pressure_temperature_humidity((int *) &sensorData->pressure, (int *) &sensorData->temperature, (int *) &sensorData->humidity);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readTemperatureLSB(Environmental_HandlePtr_T handle, int32_t *temperaturelsb)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == temperaturelsb))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

        libBme280ReturnValue = bme280_read_uncomp_temperature((int *) temperaturelsb);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readPressureLSB(Environmental_HandlePtr_T handle, int32_t *pressurelsb)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == pressurelsb))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:


        libBme280ReturnValue = bme280_read_uncomp_pressure((int *) pressurelsb);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readHumidityLSB(Environmental_HandlePtr_T handle, int32_t *humiditylsb)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == humiditylsb))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

        libBme280ReturnValue = bme280_read_uncomp_humidity((int *) humiditylsb);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }
    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readTemperature(Environmental_HandlePtr_T handle, int32_t *temperature)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    int32_t uncompensated_Temp = INT32_C(0);

    if (NULL == temperature)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }

    sensorReturnValue = Environmental_readTemperatureLSB(handle, &uncompensated_Temp);

    if (RETCODE_OK == sensorReturnValue)
    {
        *temperature = bme280_compensate_temperature_int32((int32_t) uncompensated_Temp);
        *temperature = ((*temperature) * (ENVI_BME280_TEMP_MIILIDEG_CONV));
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readPressure(Environmental_HandlePtr_T handle, uint32_t *pressure)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    int32_t uncompensated_press = INT32_C(0);

    if (NULL == pressure)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }

    sensorReturnValue = Environmental_readPressureLSB(handle, &uncompensated_press);

    if (RETCODE_OK == sensorReturnValue)
    {
        *pressure = bme280_compensate_pressure_int32((int32_t) uncompensated_press);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_readHumidity(Environmental_HandlePtr_T handle, uint32_t *humidity)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    int32_t uncompensated_Humi = INT32_C(0);

    if (NULL == humidity)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }

    sensorReturnValue = Environmental_readHumidityLSB(handle, &uncompensated_Humi);

    if (RETCODE_OK == sensorReturnValue)
    {
        *humidity = bme280_compensate_humidity_int32((int32_t) uncompensated_Humi);
        *humidity = ((*humidity) / (ENVI_BME280_HUM_RH_CONV));
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setStandbyDuration(Environmental_HandlePtr_T handle, Environmental_StandbyTime_T duration)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (ENVIRONMENTAL_STANDBY_TIME_OUT_OF_RANGE <= duration)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:
        if (duration > ENVIRONMENTAL_BME280_STANDBY_TIME_20_MS)
        {
            sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {

            libBme280ReturnValue = bme280_set_standby_durn(standbytimeLookUpTable[duration]);

            sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }
    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_getStandbyDuration(Environmental_HandlePtr_T handle, Environmental_StandbyTimePtr_T duration)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    Environmental_StandbyTime_T tempstandby = ENVIRONMENTAL_STANDBY_TIME_OUT_OF_RANGE;
    int8_t tempretVal = GET_MAPPING_ERROR;

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == duration))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

        libBme280ReturnValue = bme280_get_standby_durn((uint8_t *) duration);

        sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        if ((uint32_t) RETCODE_OK == sensorReturnValue)
        {
            tempstandby = *duration;
            tempretVal = mappingEnumForGetFunctions((uint8_t) ENVIRONMENTAL_BME280_STANDBY_TIME_1_MS, (uint8_t) ENVIRONMENTAL_BME280_STANDBY_TIME_20_MS, (uint8_t) tempstandby, standbytimeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *duration = (Environmental_StandbyTime_T) tempretVal;
            }
            else
            {
                sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }
    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setFilterCoefficient(Environmental_HandlePtr_T handle, Environmental_FilterCoefficient_T filter)
{
    Retcode_T sensorReturnValue = (uint32_t) RETCODE_FAILURE;
    BME280_RETURN_FUNCTION_TYPE libBme280ReturnValue = INT8_C(-1);

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (ENVIRONMENTAL_FILTER_COEFF_OUT_OF_RANGE <= filter)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) RETCODE_UNINITIALIZED));
    }
    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:
        if (filter > ENVIRONMENTAL_BME280_FILTER_COEFF_16)
        {
            sensorReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {
            libBme280ReturnValue = bme280_set_filter(filterCoeffLookUpTable[filter]);
            sensorReturnValue = bme280LibErrorMapping(libBme280ReturnValue);
        }
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if (RETCODE_OK != sensorReturnValue)
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setOverSamplingTemperature(Environmental_HandlePtr_T handle, Environmental_OverSampling_T samplingRate)
{
    return (setOverSampling(TEMPERATURE, handle, samplingRate));
}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setOverSamplingPressure(Environmental_HandlePtr_T handle, Environmental_OverSampling_T samplingRate)
{
    return (setOverSampling(PRESSURE, handle, samplingRate));

}

/* API documentation is in the interface header BCDS_Environmental.h*/
Retcode_T Environmental_setOverSamplingHumidity(Environmental_HandlePtr_T handle, Environmental_OverSampling_T samplingRate)
{
    return (setOverSampling(HUMIDITY, handle, samplingRate));
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Environmental_deInit(Environmental_HandlePtr_T handle)
{
    Retcode_T sensorReturnValue = (Retcode_T) RETCODE_FAILURE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t ) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE_OK);
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ENVIRONMENTAL_BME280:

        sensorReturnValue = Bme280Utils_uninitialize((Bme280Utils_InfoPtr_T) handle->SensorPtr);
        handle->SensorInformation.initializationStatus = INIT_NOT_DONE;
        break;

    default:
        sensorReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != sensorReturnValue) && (Retcode_getPackage(sensorReturnValue) == PACKAGE_ID_DEFAULT))
    {
        sensorReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t ) sensorReturnValue);
    }

    return (sensorReturnValue);
}
